package cn.imvc.app.models;

import org.hibernate.StaleObjectStateException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;

import cn.imvc.app.commons.SystemConfig;
import cn.imvc.app.entities.Account;
import cn.imvc.app.repositories.AccountRepository;
import cn.imvc.core.ICache;
import cn.imvc.data.domain.ViewRequest;
import cn.imvc.util.AES;
import cn.imvc.util.Md5;

@Service
public class AccountModelImpl implements AccountModel {

	@Autowired
	private AccountRepository accountRepository;

	@Autowired
	DealerApplyModel dealerApplyModel;

	@Autowired
	MemberModel memberModel;

	@Autowired
	ICache cache;
	
	@Autowired
	SystemConfig systemConfig;

	@Autowired
	private ApplicationContext applicationContext;

	public Account get(int id) {
		return accountRepository.findOne(id);
	}

	public Page<Account> find(ViewRequest viewRequest) {
		return (Page<Account>) accountRepository.findAll();
	}

	public Account save(Account account) {

		Account account2 = accountRepository.saveAndFlush(account);

		return account2;
	}

	public Account update(Account newAccount) {
		Account loadAccount = get(newAccount.getId());
		BeanUtils.copyProperties(newAccount, loadAccount, new String[] { "id" });

		return accountRepository.saveAndFlush(loadAccount);
	}

	public void delete(int id) {
		accountRepository.delete(id);

	}

	public void deleteBatch(int[] ids) {

		for (int id : ids) {
			delete(id);
		}

	}

	public void retrySaveAccount(Integer accountId, Integer money,Integer commissions,Integer points) {
		Account account = get(accountId);
		checkAccount(account);
		if((account.getPurse()==null?0:account.getPurse())+money<0||((account.getPoints()==null?0:account.getPoints())+points<0)){
			throw new RuntimeException();
		}
		try {
			account.setPurse((account.getPurse()==null?0:account.getPurse()) + money);
			account.setCommissions((account.getCommissions()==null?0:account.getCommissions()) + commissions);
			account.setPoints((account.getPoints()==null?0:account.getPoints())+points);
			String content=account.getPurse()+","+account.getCommissions()+","+account.getPoints();
			account.setVerify(AES.encrypt(content, systemConfig.getAESPassword()));
			save(account);		
		} catch (StaleObjectStateException e) {
			applicationContext.getBean(AccountModel.class).retrySaveAccount(accountId, money,commissions,points);
		}
	}

	public boolean checkPayPw(Account account, String password) {
		if (Md5.encode(password + (account.getKey2() == null ? "" : account.getKey2())).equals(account.getPaypwd())) {
			return true;
		} else {
			return false;
		}
	}
	
	public void checkAccount (Account account) {
		String content=account.getPurse()+","+account.getCommissions()+","+account.getPoints();
		if(!AES.encrypt(content, systemConfig.getAESPassword()).equals(account.getVerify())||account.getIsLocked()==1){
			throw new RuntimeException();			
		};
	}

}
